package it.koutifaris.travianmap.dal.sqlservices.tile;

import static it.koutifaris.testforclassutils.IsTestForAssert.assertIsTestFor;
import it.koutifaris.travianmap.TestRemoteSource;
import it.koutifaris.travianmap.dal.RevisionService.Revision;
import it.koutifaris.travianmap.dal.sqlservices.AbstractMapDbTest;
import it.koutifaris.travianmap.dal.sqlservices.dumpimporter.TravianSqlDumpImporter;
import it.koutifaris.travianmap.dal.sqlservices.revision.SqlRevisionService;
import it.koutifaris.travianmap.mapsqlparser.MapSqlParser.RemoteSource;
import it.koutifaris.travianmap.mapsqlparser.RegexMapSqlParser;
import it.koutifaris.travianmap.model.Village;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import junit.framework.Assert;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;

public class VillagesLoaderImplTest extends AbstractMapDbTest {

	private static final int TWO_VILLAGES_PLAYER_ID = 14964;
	private static final int ONE_VILLAGE_PLAYER_ID = 15008;
	private Revision revision;

	@Override
	protected void overridableSetUp() throws IOException {
		revision = new SqlRevisionService(getDbHelper().getReadableDatabase()).newRevisionForDay(new Date());
		populateDb();
	}

	public void populateDb() throws IOException {
		RegexMapSqlParser sqlParser = new RegexMapSqlParser();
		RemoteSource remoteSource = new TestRemoteSource(new Date(), getClass().getResourceAsStream("map.sql"), false);

		sqlParser.parse(
				remoteSource,
				new TravianSqlDumpImporter(getDbHelper().getWritableDatabase()));
	}

	public void testPkgAndName() {
		assertIsTestFor(VillagesLoaderImpl.class);
	}

	public void testPlayerWith2Villages() {
		VillagesLoaderImpl villagesLoader = new VillagesLoaderImpl(
				TWO_VILLAGES_PLAYER_ID,
				revision.getId());
		List<Village> villages = villagesLoader.getVillages();

		Assert.assertEquals(2, villages.size());
		Assert.assertNotNull(CollectionUtils.find(villages, new VillageIdPredicate(16363)));
		Assert.assertNotNull(CollectionUtils.find(villages, new VillageIdPredicate(16489)));
	}

	public void testPlayerWith1Village() {
		VillagesLoaderImpl villagesLoader = new VillagesLoaderImpl(
				ONE_VILLAGE_PLAYER_ID,
				revision.getId());

		List<Village> villages = villagesLoader.getVillages();

		Assert.assertEquals(1, villages.size());
		Assert.assertNotNull(CollectionUtils.find(villages, new VillageIdPredicate(16549)));
	}

	private static class VillageIdPredicate implements Predicate {

		private final int villageId;

		public VillageIdPredicate(int villageId) {
			this.villageId = villageId;
		}

		@Override
		public boolean evaluate(Object village) {
			return ((Village) village).getElementId() == villageId;
		}

	}
}
